package net.myspring.common.utils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.myspring.BlogApplication;
import net.myspring.common.domain.SearchEntity;
import net.myspring.common.mybatis.domain.PageRequest;
import net.myspring.common.mybatis.domain.Pageable;
import net.myspring.common.mybatis.domain.Sort;
import org.springframework.data.redis.core.RedisTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by liuj on 2016-08-24.
 */
public class RequestUtils {

    private static final String CACHE_PREFIX = "searchEntity_";

    public static SearchEntity getSearchEntity(HttpServletRequest request, String cacheName) {
        RedisTemplate<String, SearchEntity> redisTemplate = (RedisTemplate<String, SearchEntity>) BlogApplication.getApplicationContext().getBean("redisTemplate");
        Enumeration paramNames = request.getParameterNames();
        //Default pageable
        int pageNumber = 0;
        int pageSize = 20;
        List<String> orderList = Lists.newArrayList("id: DESC");
        Map<String, Object> params = Maps.newHashMap();
        Boolean searchFromPage = false;
        while ((paramNames != null) && paramNames.hasMoreElements()) {
            String paramName = (String) paramNames.nextElement();
            String[] paramValues = request.getParameterValues(paramName);
            if (paramValues != null && paramValues.length > 0) {
                String firstParamValue = StringUtils.isBlank(paramValues[0]) ? "" : paramValues[0].trim();
                switch (paramName) {
                    case "pageNumber":
                        if (StringUtils.isNotBlank(firstParamValue)) {
                            pageNumber = Integer.valueOf(firstParamValue);
                        }
                        break;
                    case "pageSize":
                        if (StringUtils.isNotBlank(firstParamValue)) {
                            pageSize = Integer.valueOf(firstParamValue);
                        }
                        break;
                    case "order":
                        if (Collections3.isNotEmpty(getValues(paramValues))) {
                            orderList = getValues(paramValues);
                        }
                        break;
                    case "searchFromPage":
                        searchFromPage = true;
                        break;
                    default:
                        if (paramValues.length == 1) {
                            if (StringUtils.isNotBlank(firstParamValue)) {
                                params.put(paramName, firstParamValue);
                            }
                        } else {
                            List<String> values = getValues(paramValues);
                            if (Collections3.isNotEmpty(values)) {
                                params.put(paramName, values);
                            }
                        }
                        break;
                }
            }
        }
        //如果从页面搜索，将搜索条件保存到缓存
        cacheName = CACHE_PREFIX + ThreadLocalContext.get().getAccount().getId() + "_" + cacheName;
        List<Sort.Order> orders = Lists.newArrayList();
        for (String order : orderList) {
            String direction = order.split(Const.CharEnum.COLON.getValue())[1];
            String property = order.split(Const.CharEnum.COLON.getValue())[0];
            Sort.Order sortOrder = new Sort.Order(Sort.Direction.ASC.name().equals(direction) ? Sort.Direction.ASC : Sort.Direction.DESC, property);
            orders.add(sortOrder);
        }
        Pageable pageable = new PageRequest(pageNumber, pageSize, new Sort(orders));
        SearchEntity searchEntity = new SearchEntity();
        searchEntity.setPageable(pageable);
        searchEntity.setParams(params);
        if (searchFromPage) {
            redisTemplate.opsForValue().set(cacheName, searchEntity, 3, TimeUnit.DAYS);
        } else {
            SearchEntity serverSearchEntity = redisTemplate.opsForValue().get(cacheName);
            if (serverSearchEntity != null) {
                searchEntity = serverSearchEntity;
            }
        }
        return searchEntity;
    }

    public static Boolean isAjax(HttpServletRequest request) {
        String header = request.getHeader("X-Requested-With");
        if ("XMLHttpRequest".equalsIgnoreCase(header)) {
            return true;
        } else {
            return false;
        }
    }

    private static List<String> getValues(String[] paramValues) {
        List<String> values = Lists.newArrayList();
        for (String paramValue : paramValues) {
            if (StringUtils.isNotBlank(paramValue)) {
                values.add(paramValue.trim());
            }
        }
        return values;
    }
}
